package com.intelligy.activity

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import android.widget.AdapterView.OnItemClickListener
import android.widget.ImageButton
import android.widget.ListView
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.intelligy.R
import com.intelligy.adapter.MusicListViewMainAdapter
import com.intelligy.bean.Music
import com.intelligy.databinding.ActivityMainBinding
import com.intelligy.service.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONObject
import java.net.URL
import java.nio.charset.Charset

const val HTTP_ROOT = "http://10.68.209.23:8000/"

class MainActivity : AppCompatActivity() {

    companion object {
        var isPlaying: Boolean = false
    }

    private lateinit var listView: ListView
    private lateinit var seekBar: SeekBar
    private lateinit var textViewCurr: TextView
    private lateinit var textViewTotal: TextView
    private lateinit var textViewMusicName: TextView

    private lateinit var imageButtonNext: ImageButton
    private lateinit var imageButtonPrev: ImageButton
    private lateinit var imageButtonPlay: ImageButton

    private lateinit var context: Context
    private var musicIndex = -1
    private var musics: ArrayList<Music> = ArrayList()

    private lateinit var binding: ActivityMainBinding

    private val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)

            @Suppress("UNCHECKED_CAST")
            when (msg.what) {
                1 -> playMusic(msg.obj as List<Music>)
            }
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        context = this

        init()
    }

    private fun init() {
        //从视图文件中读取各个控件以供后续使用
        listView = binding.listvMainMusicList
        seekBar = binding.skbMain
        seekBar.max = -999

        textViewCurr = binding.txtvMainCurrTime
        textViewTotal = binding.txtvMainTotalTime
        textViewMusicName = binding.txtvMainMusicTitle

        imageButtonNext = binding.imgbtnMainNext
        imageButtonPrev = binding.imgbtnMainPrev
        imageButtonPlay = binding.imgbtnMainPlay

        val listener: View.OnClickListener = View.OnClickListener {
            // 给服务设置播放列表
            val intent = Intent(context, MusicService::class.java)
            when (it!!.id) {
                imageButtonNext.id ->                       // 设置下一曲指令
                    intent.putExtra(KEY_COMMAND, CMD_NEXT)
                imageButtonPrev.id ->                       // 设置上一曲指令
                    intent.putExtra(KEY_COMMAND, CMD_PREV)
                imageButtonPlay.id -> if (isPlaying) {
                    // 设置暂停
                    intent.putExtra(KEY_COMMAND, CMD_PAUSE)
                    isPlaying = false
                    imageButtonPlay.setBackgroundResource(R.drawable.btn_play)
                } else {
                    // 设置播放指令
                    intent.putExtra(KEY_COMMAND, CMD_RESUME)
                    isPlaying = true
                    imageButtonPlay.setBackgroundResource(R.drawable.btn_pause)
                }
                else -> {
                }
            }
            // 启动服务
            startService(intent)
        }

        imageButtonNext.setOnClickListener(listener)
        imageButtonPrev.setOnClickListener(listener)
        imageButtonPlay.setOnClickListener(listener)

        // 注册音乐播放状态更新的接受器
        // 特别说明通过动态注册的方式注册的广播接受器，在程序推出前必须要注销，一般写在 onDestroy 中。
        // 不注销的话推出程序会报错
        val musicReceiver = MusicReceiver()
        val musicReceiverFilter = IntentFilter(CAST_ACTION_UPDATE)
        registerReceiver(musicReceiver, musicReceiverFilter)

        // listView 点击事件
        listView.onItemClickListener =
            OnItemClickListener { _, _, position, _ ->
                val intent = Intent(context, MusicService::class.java)

                // 设置初始化指令
                intent.putExtra(KEY_COMMAND, CMD_PLAY)

                // 传递播放位置
                intent.putExtra(KEY_MUSIC_INDEX, position)

                // 启动服务
                startService(intent)
                isPlaying = true
                imageButtonPlay.setBackgroundResource(R.drawable.btn_pause)
            }

        // 进度条滑动事件
        seekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    val intent = Intent(context, MusicService::class.java)
                    intent.putExtra(KEY_POSITION, progress)
                    intent.putExtra(KEY_COMMAND, CMD_PLAY_TIME)
                    seekBar.progress = progress
                    startService(intent)
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
            }
        })

        GlobalScope.launch {
            loadMusics()
        }
    }

    private fun playMusic(musics: List<Music>) {
        // JSON 解析完成后，将音乐列表数据传给适配器
        val adapter = MusicListViewMainAdapter(musics, context)
        listView.adapter = adapter

        // 给服务设置播放列表
        val intent = Intent(context, MusicService::class.java)

        // 解析播放列表获取播放路径
        val musicList = ArrayList<String>()
        for (music in musics) {
            musicList.add(HTTP_ROOT + music.path)
        }

        // 设置初始化指令
        intent.putExtra(KEY_COMMAND, CMD_INIT)

        // 传递初始化数据
        intent.putStringArrayListExtra(KEY_MUSIC_LIST, musicList)

        // 启动服务
        startService(intent)
    }

    private fun loadMusics() {
        val url = URL(HTTP_ROOT + "music.json")
        val conn = url.openConnection()

        conn.connect()

        val dataStr = conn.getInputStream().use {
            String(it.readBytes(), Charset.forName("utf-8"))
        }

        // 从 json 中解析出音乐列表
        val array = JSONArray(dataStr)
        musics = ArrayList()
        var music: Music
        for (i in 0 until array.length()) {
            val jsonObject: JSONObject = array.getJSONObject(i)
            music = Music(
                jsonObject.getString("name"),
                jsonObject.getString("mp3"),
                jsonObject.getString("singer")
            )
            musics.add(music)
        }
        val msg = Message()
        msg.what = 1
        msg.obj = musics
        handler.sendMessage(msg)
    }

    /**
     * 播放进度更新时的广播接受器
     */
    inner class MusicReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {

            // 从广播中解析各种数据
            intent?.let {
                it.apply {
                    val index = getIntExtra(KEY_MUSIC_INDEX, 0)
                    val curr = getIntExtra(MUSIC_TIME_CURR, 0)
                    val total = getIntExtra(MUSIC_TIME_TOTAL, 0)

                    // 如果播放的位置发生变化说明已经播放另一首歌曲了，此时需要更新音乐封面名称
                    if (musicIndex != index) {
                        musicIndex = index
                        // 设置进度条的最大值
                        seekBar.max = total
                        textViewTotal.text = msToString(total)
                        textViewMusicName.text = musics[musicIndex].title
                        // 当开始播放后，将播放按钮换成暂停
                        imageButtonPlay.setBackgroundResource(R.drawable.btn_pause)
                    }
                    // 设置当前进度条的当前播放值
                    seekBar.progress = curr
                    textViewCurr.text = msToString(curr)
                }
            }
        }

        private fun msToString(time: Int): String {
            val sTemp = time / 1000
            val m = sTemp / 60
            val s = sTemp % 60
            var strM = m.toString()
            var strS = s.toString()
            if (m < 10) {
                strM = "0$m"
            }
            if (s < 10) {
                strS = "0$s"
            }
            return "$strM:$strS"
        }
    }
}